<?php
namespace app\admin\controller;

use app\admin\model\Catelog as CatelogModel;
use app\admin\model\Video as VideoModel;
use app\BaseController;
use think\facade\View;
use think\facade\Db;
use think\facade\Filesystem;
use think\facade\Request;
use think\facade\Validate;
class Video extends BaseController
{
    public function index()
    {
        $res = VideoModel::with('cate')->select();
        return View::fetch('',[
            'res'=>$res,
        ]);
    }

    public function add(){
        if (Request::isPost()){
            $data = input('post.');
            $res = VideoModel::create($data);
            if($res->id){
                return redirect('/admin/Video/index');
            }
            new \Exception('添加视频过程中出现了错误!请查看');
        } else {
            $cates = CatelogModel::select();
            return View::fetch('',[
                'cates'=>$cates,
            ]);
        }
    }
    public function upload_chunk()
    {
        header("Access-Control-Allow-origin:*");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        // 获取请求信息
        $file = Request::file('file'); // 假设前端文件字段名为file
        $chunk = Request::param('chunk'); // 当前分片索引
        $chunks = Request::param('chunks'); // 总分片数
        $identifier = Request::param('identifier'); // 文件唯一标识符，用于合并文件

        if (!$file) {
            return json(['error' => 'No file uploaded', 'status' => 0]);
        }

        // 保存分片文件
        $saveName = "chunk_{$file->getOriginalName()}"; // 分片保存的文件名
        $disk = Filesystem::disk('public'); // 假设使用public磁盘
        $result = $disk->putFileAs($saveName, $file, "chunk_{$chunk}");

        if (!$result) {
            return json(['error' => 'Failed to save chunk', 'status' => 0]);
        }
        $isLastChunk = ($chunk == $chunks-1);
        // 在这里可以添加更多的逻辑，比如检查分片是否全部上传完成等

        return json(['code'=>200,'msg' => 'Chunk uploaded successfully', 'isLastChunk' => $isLastChunk]);
        //检查文件流
        //$rawData = file_get_contents('php://input');
        //if ($rawData === false) return json(['code'=>400,'msg'=>'无法读取文件流']);
        //创建临时目录
        /*try{
            $tempDir = app()->getRootPath() . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR;
        } catch(\Exception $e) {
            return $e->getMessage();
        }
        if (!is_dir($tempDir)) mkdir($tempDir, 0777, true);
        $chunk_path = $tempDir . $filename . '_' ;//当前分片名称
        //file_put_contents($chunk_path, $rawData);
        Filesystem::disk('public')->putFile('topic', $file);*/
    }
    public function merge_chunks()
    {
        header("Access-Control-Allow-origin:*");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            exit;
        }
        //获取到分片的存储目录
        $chunkDir = config('filesystem.disks')['public']['root'] ? config('filesystem.disks')['public']['root'] . '/' : 'D:/web/video.cn/public/storage/';
        //$chunkDir .=   'chunk_' . input('param.fileName');
        if (!$chunkDir) throw new \Exception('您的分片目录不存在，请重试！');
        //需要进行分片列表遍历了
        $chunks = [];
        $filename = input('fileName');
        $ext = pathinfo($filename,PATHINFO_EXTENSION);
        $chunk_dirs = str_replace('\\','/',$chunkDir. 'chunk_' . $filename);
        foreach (scandir($chunk_dirs)  as $file) {
            if ('.' == $file || '..' == $file) {
                continue;
            }
            if (preg_match("/^chunk_(\d+)$/", $file, $matches)) {
                $chunkIndex = intval($matches[1]);
                $chunks[$chunkIndex] = $file;
            }
        }
        // 对分片进行排序
        ksort($chunks);
        // 打开输出文件，准备写入
        //$outputFile = fopen($chunkDir . $filename . '.' . $ext, 'wb');
        $outputFile = fopen($chunkDir . $filename, 'wb');
        if (!$outputFile) {
            return json(['error' => 'Failed to open output file', 'status' => 0]);
        }

        // 读取每个分片并写入输出文件
        foreach ($chunks as $chunkFile) {
            $chunkPath = $chunkDir .'chunk_' . $filename. '/'. $chunkFile;
            $chunkContent = file_get_contents($chunkPath);
            if ($chunkContent === false) {
                fclose($outputFile); // 关闭输出文件
                unlink($chunkDir . $outputFile); // 删除已写入的部分
                return json(['error' => "Failed to read chunk file {$chunkFile}", 'status' => 0]);
            }
            fwrite($outputFile, $chunkContent);
        }

        // 关闭输出文件
        fclose($outputFile);

        // （可选）删除分片文件
        foreach ($chunks as $chunkFile) {
            @unlink($chunkDir  .'chunk_' . $filename. '/'. $chunkFile);
        }

        @rmdir($chunkDir  .'chunk_' . $filename);
        //合并后的文件$chunkDir . $filename,需要进行命令转码并生成对应的m3u8文件
        //设置输出目录
        $outputDirectory = $chunkDir . $filename . '_m3u8/';
        if(!is_dir($outputDirectory)){
            @mkdir($outputDirectory,0777,true);
        }
        // 构建FFmpeg命令
        $videoPath = str_replace('\\','/',$chunkDir . $filename);
        $outputDirectory = str_replace('\\','/',$outputDirectory);
        $command = "D:/gongju/ffmpeg-7.0.1/bin/ffmpeg.exe -i {$videoPath} -c:v libx264 -preset veryfast -b:v 256K -maxrate 384K -bufsize 2M -c:a aac -b:a 128k -hls_time 50 -hls_list_size 0 -hls_flags delete_segments  -hls_segment_filename {$outputDirectory}/playlist_%d.ts {$outputDirectory}/playlist.m3u8";
        // 执行命令
        shell_exec($command);

        return json(['msg' => "File merged successfully", 'status' => 1, 'filename' => $filename]);
    }
}